﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using log4net;
using TanHungViet.Helper;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace TanHungViet.Web.Models
{
    public partial class FileInfo
    {
        public string FileTitle { get; set; }
        public string FileTitle2 { get; set; }

        public FileInfo() { }
        public FileInfo(string fileTitle, DateTime publishDate, string extension, long countDownloaded)
        {
            FileID = 0;
            FileTitle = fileTitle;
            PublishDate = publishDate;
            FileExtension = extension ?? string.Empty;
            CountDownloaded = 0;

            FileTitle2 = string.Empty;
        }
    }

    [Bind(Exclude = "FileID")]
    public class FileInfoValidation
    {
        [Required(ErrorMessage = "Tên tập tin không được bỏ trống")]
        [StringLength(200, ErrorMessage = "Tên tập tin không được vượt quá 200 ký tự!")]
        public string FileTitle { get; set; }
    }

    public class FileInfoRepository
    {
        private static ILog _logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private DBTanHungVietEntities _db;

        public FileInfoRepository(DBTanHungVietEntities entity)
        {
            _db = entity;
        }

        public IQueryable<FileInfo> GetListFileByContentCode(string contentCode)
        {
            try
            {
                _logger.InfoFormat("Begin GetListFileByContentCode({0})", contentCode);

                var content = _db.Content.FirstOrDefault(b => b.ContentCode == contentCode);
                if (content == null)
                    return null;

                var list = from b in _db.FileInfo
                           where b.ContentID == content.ContentID
                           select b;

                foreach (var item in list)
                {
                    var tempVN = _db.FileInfoDetail.FirstOrDefault(
                        b => b.FileID == item.FileID
                            && b.LanguageID == 1);

                    if (tempVN == null)
                        _logger.Error("Content has no detail");
                    else
                        item.FileTitle = tempVN.FileTitle ?? string.Empty;
                }

                _logger.Info("End GetListFileByContentCode ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<FileInfo> GetFullListFile()
        {
            try
            {
                _logger.Info("Begin GetFullListFile({0})");

                var list = from b in _db.FileInfo
                           select b;

                foreach (var item in list)
                {
                    var tempVN = _db.FileInfoDetail.FirstOrDefault(
                        b => b.FileID == item.FileID
                            && b.LanguageID == 1);

                    if (tempVN == null)
                        _logger.Error("Content has no detail");
                    else
                        item.FileTitle = tempVN.FileTitle ?? string.Empty;

                    var tempUS = _db.FileInfoDetail.FirstOrDefault(
                        b => b.FileID == item.FileID
                            && b.LanguageID == 2);
                    if (tempUS != null)
                        item.FileTitle2 = tempUS.FileTitle;
                }

                _logger.Info("End GetFullListFile ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public FileInfo GetFullFileInfoByCode(string code)
        {
            try
            {
                _logger.InfoFormat("Begin GetFullFileInfoByCode({0})", code);

                var fileInfo = _db.FileInfo.FirstOrDefault(b => b.FileCode == code);
                if (fileInfo == null)
                    return null;

                var detail = _db.FileInfoDetail.FirstOrDefault(b => b.FileID == fileInfo.FileID
                    && b.LanguageID == 1);
                if (detail == null)
                    return null;

                fileInfo.FileTitle = detail.FileTitle;

                _logger.Info("End GetFullFileInfoByCode ....");
                return fileInfo;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public FileInfo GetFullFileInfoByID(int id)
        {
            try
            {
                _logger.InfoFormat("Begin GetFullFileInfoByID({0})", id);

                var fileInfo = _db.FileInfo.FirstOrDefault(b => b.FileID == id);
                if (fileInfo == null)
                    return null;

                var detail = _db.FileInfoDetail.FirstOrDefault(b => b.FileID == fileInfo.FileID
                    && b.LanguageID == 1);
                if (detail == null)
                    return null;

                fileInfo.FileTitle = detail.FileTitle;

                _logger.Info("End GetFullFileInfoByID ....");
                return fileInfo;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public int AddNewFile(FileInfo newFile, string parentContentCode)
        {
            try
            {
                _logger.Info("Begin AddNewFile()");
                int result = -1;

                var content = _db.Content.FirstOrDefault(b => b.ContentCode == parentContentCode);
                if (content == null)
                    return result;

                newFile.ContentID = content.ContentID;
                newFile.CountDownloaded = 0;
                newFile.PublishDate = DateTime.Now;
                // kiem tra file code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    FileInfo checkFile = GetFullFileInfoByCode(newFile.FileCode);
                    if (checkFile != null)
                    {
                        newFile.FileCode += "-1";
                        _logger.InfoFormat("New file code is ({0})", newFile.FileCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);
                _db.AddToFileInfo(newFile);
                _db.SaveChanges();

                string title = newFile.FileTitle;
                newFile = _db.FileInfo.FirstOrDefault(b => b.FileCode == newFile.FileCode);
                result = newFile.FileID;
                FileInfoDetail detail = new FileInfoDetail();
                detail.LanguageID = 1;
                detail.FileID = newFile.FileID;
                detail.FileTitle = title;
                _db.AddToFileInfoDetail(detail);
                _db.SaveChanges();

                _logger.Info("End AddNewFile ....");
                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public string UpdateFile(FileInfo updateFile)
        {
            try
            {
                _logger.InfoFormat("Begin UpdateFile() with file ID = {0}", updateFile.FileID);
                string oldFileName = string.Empty;

                var file = _db.FileInfo.FirstOrDefault(b => b.FileID == updateFile.FileID);
                if (file == null)
                    return oldFileName;

                oldFileName = file.FileCode + file.FileExtension;
                file.PublishDate = DateTime.Now;
                if (!string.IsNullOrEmpty(updateFile.FileExtension))
                    file.FileExtension = updateFile.FileExtension;
                file.FileCode = updateFile.FileCode;
                // kiem tra file code da ton tai chua
                if (!updateFile.FileCode.Equals(file.FileCode))
                {
                    bool checkExistCode = true;
                    do
                    {
                        FileInfo checkFile = _db.FileInfo.FirstOrDefault(b => b.FileCode == file.FileCode);
                        if (checkFile != null)
                        {
                            file.FileCode += "-1";
                            _logger.InfoFormat("New file code is ({0})", file.FileCode);
                        }
                        else
                            checkExistCode = false;
                    } while (checkExistCode);
                }
                
                // update file detail
                var detail = _db.FileInfoDetail.FirstOrDefault(b => b.LanguageID == 1 && b.FileID == updateFile.FileID);
                if(detail!=null)
                    detail.FileTitle = updateFile.FileTitle;

                _db.SaveChanges();
                _logger.Info("End UpdateFile ....");
                return oldFileName;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public string DeleteFiles(string lstId)
        {
            try
            {
                _logger.InfoFormat("Begin DeleteFiles({0})", lstId);
                string result = string.Empty;
                string[] arr = lstId.Split('-');

                foreach (string id in arr)
                {
                    if (id.Length > 0)
                    {
                        int idDelete = int.Parse(id);
                        FileInfo deleteFile = _db.FileInfo.FirstOrDefault(b => b.FileID == idDelete);
                        if (deleteFile != null)
                        {
                            result += id + deleteFile.FileExtension + "-";
                            FileInfoDetail deleteDetail = _db.FileInfoDetail.FirstOrDefault(b => b.FileID == idDelete &&
                                b.LanguageID == 1);
                            if (deleteDetail != null)
                                _db.DeleteObject(deleteDetail);

                            _db.DeleteObject(deleteFile);
                        }
                    }
                }

                _db.SaveChanges();
                _logger.Info("End DeleteFiles()");

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public FileInfo DownloadFile(string code)
        {
            try
            {
                _logger.InfoFormat("Begin DownloadFile({0})", code);
                FileInfo result = null;

                var file = GetFullFileInfoByCode(code);
                if (file != null)
                {
                    file.CountDownloaded += 1;
                    result = file;
                    _db.SaveChanges();
                }

                _logger.InfoFormat("End DownloadFile({0})", code);
                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

    }
}
